package com.lagou.utils.aspect;

import com.alibaba.fastjson.JSON;
import com.lagou.response.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * 自定义切面
 */
@Component
@Aspect
@Slf4j
public class CustomAspect {

    @Autowired
    private HttpServletRequest request;

    private static final String TARGET = "@annotation(org.springframework.web.bind.annotation.RequestMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping)";

    /**
     * 响应数据日志打印
     *
     * @param result 接口返回值
     * @return result
     */
    @AfterReturning(value = "@annotation(org.springframework.web.bind.annotation.RequestMapping)", returning = "result")
    public Object afterReturning(Object result) {
        if (!(result instanceof ResponseResult)) {
            return result;
        }
        // 可以通过AOP功能改变响应体中的字段值
        ResponseResult<Object> responseResult = (ResponseResult<Object>) result;
        Object content = responseResult.getContent();
        content = JSON.toJSONString(content);
        responseResult.setContent(content);
        log.info("response result log =========> {}", JSON.toJSONString(result));
        return result;
    }

    /**
     * 环绕通知
     *
     * @param joinPoint 连接点
     * @return 拦截放行
     * @throws Throwable 异常
     */
    @Around(value = "@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        return joinPoint.proceed();
    }

    /**
     * 前置通知 对入参进行日志打印
     *
     * @param joinPoint 拦截点
     */
    @Before(value = "@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public void before(JoinPoint joinPoint) {
        String url = request.getRequestURL().toString();
        log.info("ip and url is {}", url);

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        String[] parameterNames = signature.getParameterNames();
        Object[] args = joinPoint.getArgs();
        // 请求参数日志map  key参数名=====》value参数值
        Map<String, Object> paramMap = new HashMap<>();
        if (parameterNames.length == args.length) {
            for (int i = 0; i < parameterNames.length; i++) {
                paramMap.put(parameterNames[i], args[i]);
            }
        }
        log.info("parameterMap ===== methodTye {} =====> {}", request.getMethod(), JSON.toJSONString(paramMap));
    }
}
